<template>
  <div>
    <!-- 上传图片 -->
    <el-upload
      :limit="limit"
      :list-type="isButton ? '' : 'picture-card'"
      ref="upload"
      class="upload_img"
      :class="[{upload_avatar: isAvatar}, {hideUpload: (isAvatar && imgList.length === 1) || imgList.length === limit || disabled}]"
      name="uploadFile"
      :show-file-list="!isButton"
      :file-list="imgList"
      :callback="callback"
      :on-success="_uploadSuccess"
      :on-error="_uploadError"
      :on-remove="_uploadRemove"
      :before-upload="_beforeUpload"
      :disabled="isLoading"
      :action="uploadStreamUrl">
      <el-button v-if="isButton" size="small" type="primary" :loading="isLoading">{{isLoading ? '上传中' : '点击上传'}}</el-button>
      <i v-else class="el-icon-plus" :class="{avatar_icon: isAvatar}"></i>
      <em class="avatar_em" v-if="tip">{{tip}}</em>
    </el-upload>
    <!-- 查看大图 -->
    <picture-viewer ref="imageViewer"></picture-viewer>

  </div>
</template>

<script>
import { uploadUrl } from '@/services/model/common'
import constUrl from '@/services/env'
import PictureViewer from '@/components/picture-viewer'

export default {
  components: { PictureViewer },

  props: {
    callback: {
      type: String,
    default: null
    },
    // 张数限制

    limit: {
      type: Number,
      default: 9
    },
    // 张数限制
    disabled: {
      type: Boolean,
      default: false
    },
    // 上传头像请用 :value="" 直接传值， form表单请用 v-model绑定  在imgList set方法中会触发不通方法
    value: {
      type: null,
    },
    // 单位M
    sizeLimit: {
      type: Number,
      default: 1
    },
    // 上传头像标志位 该标志位仅对  张数、入参、回参有区别
    avatar: {
      type: null,
      default: null
    },
    // =button  通过按钮触发  否则通过+触发
    trigger: {
      type: null,
      default: null
    },
    // 上传提示信息
    tip: {
      type: String
    }
  },
  data () {
    return {
      // 文件上传流url
      uploadStreamUrl: uploadUrl,
      // el-upload的组件列表 刚进入时由于 v-model绑定传值的 value由于异步原因不一定有值，所以在刚加载页面时不能对imgListModel赋值
      // 第一次回显读取图片取 vallue中的值
      imgListModel: null,
      // 查看图片序列值
      previewIndex: 0,
      // 接口正在加载
      isLoading: false,
    }
  },
  computed: {
    // 是否为上传头像
    isAvatar () {
      return this.avatar !== null
    },
    // 是否通过按钮触发
    isButton () {
      return this.trigger === 'button'
    },
    // 图片 model
    imgList: {
      get () {
        //  ******！！！  第一次进入时this.imgListModel为null所以取this.value的值  但上传之后，imgListModel一定有值。为了修复上传闪动的bug,第一次进入时取
        return this.imgListModel || this.initList.map(x => ({ url: constUrl + x }))
      },
      set (list) {
        // 如果是按钮模式，则始终为空数组
        this.imgListModel = this.isButton ? [] : list
        // 将ul-upload 返回带response的对象格式  以及回显的  对象格式全部转化为 后端需要的字符串路径
        list = list.map(x => x.response ? x.response.data.path : x.url.replace(constUrl, ''))
        // 头像只更新 url  ， 图片列表更新列表
        let params = this.isAvatar ? list[0] : list
        this.$emit('input', params)
        this.$emit('update', params)
      }
    },
    initList () {
      let initList
      // 上传头像模式 value 传入的是字符窜，而不是数组。
      if (this.isAvatar) initList = this.value ? [this.value] : []
      // 图片列表
      else initList = this.value || []
      return initList
    },
  },
  methods: {
    // 清空列表
    reset () {
      this.imgList = []
    },
    clears () { // 清空图片
      this.$refs.upload.clearFiles()
    },

    /**
     * 上传文件之前的钩子，参数为上传的文件
     * 若返回 false 或者返回 Promise 且被 reject，则停止上传。
     */
    _beforeUpload (file) {
      // 文件类型
      const FILE_TYPE = file.type
      // 文件大小
      const FILE_SIZE = Number(file.size || 0)
      // 允许上传的图片的类型
      const ALLOW_LIST = ['image/jpeg', 'image/png']
      // 4M限制
      const FILE_SIZE_LIMIT = 1024 * 1024 * this.singleSize
      if (!ALLOW_LIST.includes(FILE_TYPE) || FILE_SIZE > FILE_SIZE_LIMIT) {
        // 文件类型不符提示信息
        const TYPE_INFO = '只能上传图片'
        // 文件大小超出限制提示信息
        const TYPE_SIZE = `文件大小限制${this.singleSize}M以内`
        const INFO_MSG = !ALLOW_LIST.includes(FILE_TYPE) ? TYPE_INFO : TYPE_SIZE
        this.$message.error(INFO_MSG)
        return false
      }
      this.isLoading = true
    },
    // 上传错误
    _uploadError (err) {
      this.$message.error('上传失败:' + err)
      this.isLoading = false
    },
    // 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
    _uploadRemove (file, fileList) {
      this.imgList = fileList
    },
    /**
     * 文件上传成功时的钩子
     */
    _uploadSuccess (res, file, fileList) {
      this.isLoading = false
      if (res.code === 200) {
        if(this.callback){
          this.$emit(this.callback,fileList[fileList.length-1].response.data.path)

        }
        this.$message.success('图片已上传')
      } else this.$message.error(res.message)
    },
  }
}
</script>
<style lang="less" scoped>
.upload_img /deep/.el-upload.el-upload--picture-card {
  display: inline-flex;
  flex-direction: column;
  line-height: 1 !important;
  align-items: center;
  justify-content: center;
}
/** 主题切换相关 */
.theme-light{
  @upload-img-avatar-text: #515563;

  .init-theme();
}

.theme-dark{
  @upload-img-avatar-text: #D2D7ED;

  .init-theme();
}
.init-theme () {
  .upload_avatar {
    position: relative;
    width: 80px;
    height: 80px;
    /deep/.el-upload.el-upload--picture-card {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
    }
    /deep/.el-upload-list.el-upload-list--picture-card {
      position: relative;
      z-index: 2;
      .el-upload-list__item {
        width: 100%;
        height: 100%;
        margin: 0;
        .el-upload-list__item-status-label {
          position: absolute;
          display: none;
        }
      }
    }
    /deep/.el-upload-list__item.el-list-leave-active {
      transition: none !important;
    }
    .avatar_em {
      color: @upload-img-avatar-text;
      font-size: 14px;
      line-height: 20px;
    }
    .avatar_icon {
      font-size: 20px;
      margin-bottom: 6px;
      font-weight: bold;
    }
  }
}
.hideUpload {
  /deep/.el-upload--picture-card {
    display: none !important;
  }
}
</style>
